package com.legrand.core.util;

import org.apache.commons.lang3.StringUtils;
import java.sql.Time;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期工具
 *
 * @author xiah
 */
public class DateUtil {

    public static String DATA_FORMAT = "yyyy-MM-dd";

    public static String DATA_FORMAT2 = "yyyy/MM/dd";

    public static String DATA_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static String DATA_TIME_FORMAT2 = "yyyyMMddHHmmss";

    public static String DATA_TIME_FORMAT3 = "yyyy-MM-dd HH:mm";

    public static String DATA_TIME_FORMAT4 = "yyyy-MM-dd HH";

    public static String TIME_FORMAT = "HH:mm";

    public static String TIME_FORMAT2 = "HH:mm:ss";

    /**
     * 时间间隔
     **/
    public static long TIME_INTERVAL = 0L;

    /**
     * 星期
     */
    public static interface WEEK {

        /**
         * 周日
         **/
        int Sun = 1;

        /**
         * 周一
         **/
        int Mon = 2;

        /**
         * 周二
         **/
        int Tues = 3;

        /**
         * 周三
         **/
        int Wed = 4;

        /**
         * 周四
         **/
        int Thur = 5;

        /**
         * 周五
         **/
        int Fri = 6;

        /**
         * 周六
         **/
        int Sat = 7;
    }

    /**
     * 获取今天星期几，索引从周日开始。 1周日，2周一，3周二.....
     *
     * @return
     */
    public static int getWeekDay() {
        return getWeekDayByDate(new Date());
    }

    /**
     * 根据传入日期，获取星期
     *
     * @param date
     * @return
     */
    public static int getWeekDayByDate(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_WEEK);
    }


    /**
     * 获得日期字符串
     *
     * @param date
     * @return
     */
    public static String getDateString(Date date) {
        return getDateString(date, DATA_FORMAT);
    }

    /**
     * 获得日期字符串
     *
     * @param date
     * @return
     */
    public static String getDateString(Date date, String format) {
        if (null == date){
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * 获得当前日期字符串
     *
     * @param
     * @return
     */
    public static String getTodayDateString() {
        return getDateString(new Date());
    }

    /**
     * 获得当前日期字符串
     *
     * @param format
     * @return
     */
    public static String getTodayDateString(String format) {
        return getDateString(new Date(), format);
    }

    /**
     * 获得当前日期字符串
     *
     * @param
     * @return
     */
    public static Date getDateWithoutHour(Date d) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(d);
        Calendar c2 = Calendar.getInstance();
        c2.set(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH), c1.get(Calendar.DATE), 0, 0, 0);
        return c2.getTime();
    }

    /**
     * 获得时间格式化字符串HH:mm
     *
     * @param time
     * @return
     */
    public static String getTimeString(Time time) {
        if (null == time){
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
        return sdf.format(time);
    }

    /**
     * 获得指定时间格式化字符串
     *
     * @param time
     * @return
     */
    public static String getTimeString(Time time, String formatter) {
        if (null == time){
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(formatter);
        return sdf.format(time);
    }

    /**
     * 获得时间格式化字符串HH:mm
     * @param time
     * @return
     */
    public static String getTimeString(Date time) {
        if (null == time){
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
        return sdf.format(time);
    }

    /**
     * 获得时间格式化字符串HH:mm:ss
     *
     * @param t
     * @return
     */
    public static String getTimeStringHHMMSS(String t) {
        if (StringUtils.isEmpty(t)){
            return null;
        }
        Time time;
        try {
            time = parseTime(t);

            SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT2);
            return sdf.format(time);
        } catch (ParseException e) {
            return t;
        }
    }

    /**
     * 在传入时间内增加半小时
     *
     * @param time
     * @return
     */
    public static Time addHalfHours(Time time) {
        if (null == time){
            return null;
        }
        return new Time(time.getTime() + getHalfHoursMillisecond());
    }

    /**
     * 时间t1加上minute分钟后的时间
     *
     * @return
     */
    public static Time addTime(Time t1, int minute) {
        if (null == t1) {
            return null;
        }
        return new Time(t1.getTime() + minute * 1000 * 60);
    }

    public static Time addTime(Date t1, int minute) {
        if (null == t1) {
            return null;
        }
        return new Time(t1.getTime() + minute * 1000 * 60);
    }

    /**
     * 在传入时间内增加半小时半转成字符串
     *
     * @param time
     * @return
     */
    public static String addHalfHoursString(Time time) {
        return getTimeString(addHalfHours(time));
    }

    public static String addHalfHoursString(String time) {
        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
        Time t;
        try {
            t = new Time(sdf.parse(time).getTime());
        } catch (ParseException e) {
            return time;
        }
        return getTimeString(addHalfHours(t));
    }

    /**
     * 得到半个小时毫秒
     *
     * @return
     */
    public static long getHalfHoursMillisecond() {
        return 30 * 60 * 1000;
    }

    public static Date parseDate(Object o) throws ParseException {
        return parseDate(o, DATA_FORMAT);
    }

    public static Date parseDate(Object o, String format) throws ParseException {
        if (o instanceof Number) {
            return parseDate(new Date((Long) o), format);
        } else if (o instanceof Date) {
            return (Date) o;
        } else {
            return parseDate(o.toString(), format);
        }
    }

    public static Date parseDate(String date) throws ParseException {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        if (date.length() >= 19) {
            return parseDate(date, DATA_TIME_FORMAT);
        } else if (date.length() >= 16) {
            return parseDate(date, DATA_TIME_FORMAT3);
        } else if (date.length() >= 13) {
            return parseDate(date, DATA_TIME_FORMAT4);
        }
        return parseDate(date, DATA_FORMAT);
    }

    public static Date parseDate(String date, String format) throws ParseException {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.parse(date);
    }

    public static Time parseTime(String date) throws ParseException {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(TIME_FORMAT);
        return new Time(format.parse(date).getTime());
    }

    public static Time parseTime(Date date) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(TIME_FORMAT);
        return new Time(format.parse(getDateString(date, TIME_FORMAT2)).getTime());
    }

    /**
     * 传入时间与现在时间比较，返回比现在时间大多少毫秒
     *
     * @param time
     * @return
     */
    public static Long compareNow(Time time) {
        try {
            Time nowTime = parseTime(getDateString(new Date(), TIME_FORMAT));
            return compareTime(time, nowTime);
        } catch (ParseException e) {
            return -1L;
        }
    }

    /**
     * 传入时间与现在时间比较，返回比现在时间大多少毫秒
     *
     * @param
     * @return
     */
    public static Long compareNow(Date date) {
        try {
            Time nowTime = parseTime(getDateString(new Date(), TIME_FORMAT));
            return compareTime(parseTime(date), nowTime);
        } catch (ParseException e) {
            return -1L;
        }
    }

    /**
     * 传入时间比较，返回t2比t1时间大多少毫秒
     *
     * @param
     * @return
     */
    public static Long compareTime(Time t1, Time t2) {
        return t2.getTime() - t1.getTime();
    }

    /**
     * 获取某一时间段特定星期几的日期
     */
    public static List<Date> getDateByTimeInterval(Date startDate, Date endDate, Integer weekNumber) {
        long time = 1l;
        long perDayMilSec = 24 * 60 * 60 * 1000;
        List<Date> dateList = new ArrayList<Date>();
        startDate = new Date(startDate.getTime() - perDayMilSec);
        while (true) {
            time = startDate.getTime();
            time = time + perDayMilSec;
            startDate = new Date(time);
            if (startDate.compareTo(endDate) <= 0) {
                // 查询的某一时间的星期系数
                Integer weekDay = getWeekDayByDate(startDate);
                // 判断当期日期的星期系数是否是需要查询的
                if (weekNumber == weekDay) {
                    dateList.add(startDate);
                }
            } else {
                break;
            }
        }
        return dateList;
    }

    /**
     * 获取某一时间段特定星期几的日期
     */
    public static List<String> getDateByTimeInterval(String startDate, String endDate, Integer weekNumber) {
        SimpleDateFormat sdf = new SimpleDateFormat(DATA_FORMAT);
        List<String> result = new ArrayList<String>();
        try {
            List<Date> dates = getDateByTimeInterval(sdf.parse(startDate), sdf.parse(endDate), weekNumber);
            for (Date item : dates) {
                result.add(sdf.format(item));
            }
        } catch (ParseException e) {
            return null;
        }
        return result;
    }

    /**
     * 两个日期相减得到秒(d1-d2)
     *
     * @param d1
     * @param d2
     * @return
     */
    public static long subtractionSec(Date d1, Date d2) {

        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(d1);
        cal2.setTime(d2);
        long t1 = cal1.getTimeInMillis();
        long t2 = cal2.getTimeInMillis();
        long sec = (t1 - t2) / 1000;
        return sec;
    }

    /**
     * 两个日期相减得到天(d1-d2)
     *
     * @param d1
     * @param d2
     * @return
     */
    public static long subtractionDay(Date d1, Date d2) {
        if (null == d1 || null == d2) {
            return 0;
        }
        long sec = subtractionSec(d1, d2);
        return sec / 86400;
    }

    /**
     * 传入日期加qty天
     */
    public static Date addDate(Date d, int qty) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        calendar.add(Calendar.DATE, qty);
        return calendar.getTime();
    }

    /**
     * 传入日期加qty月
     */
    public static Date addDateMonth(Date d, int qty) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        calendar.add(Calendar.MONTH, qty);
        return calendar.getTime();
    }

    /**
     * 传入日期加minute分钟
     */
    public static Date addDateTime(Date d, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    /**
     * 传入日期加seconds秒钟
     */
    public static Date addSecond(Date d, int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        calendar.add(Calendar.SECOND, seconds);
        return calendar.getTime();
    }

    /**
     * 当前日期增加qty天
     */
    public static Date addDate(int qty) {
        return addDate(new Date(), qty);
    }

    public static Date today() {
        SimpleDateFormat f = new SimpleDateFormat(DATA_FORMAT);
        Date now = null;
        try {
            now = f.parse(getTodayDateString());
        } catch (ParseException e) {
            // Impossible
        }
        return now;
    }

    public static Date timeNow() {
        SimpleDateFormat f = new SimpleDateFormat(TIME_FORMAT);
        Date now = null;
        try {
            now = f.parse(getTodayDateString(TIME_FORMAT));
        } catch (ParseException e) {
            // Impossible
        }
        return now;
    }

    /**
     * 计算2个日期之间相差的天数 2016-09-24修复时间可能在开始时间之前的bug-->王全志
     *
     * @return
     */
    public static List<Date> betweenDay(Date start, Date end) {
        if (start == null || end == null || start.after(end)) {
            return new ArrayList<Date>(0);
        }
        int s = (int) ((end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000));
        List<Date> dateList = new ArrayList<Date>(s);
        for (int i = 0; i <= s; i++) {
            dateList.add(DateUtil.addDate(start, i));
            /* new Date(start.getTime() + i * 24 * 60 * 60 * 1000)); */
        }
        return dateList;
    }

    /**
     * 调用原生态比较时间方法 （没有幽灵情况出现）
     *
     * @param d1
     * @return
     */
    public static int compareNowDate(Date d1) {
        return new Date().compareTo(d1);
    }

    public static Date timePiece2Date(Date date, String timePiece) throws ParseException {
        return parseDate(getDateString(date, DATA_FORMAT) + " " + timePiece, DATA_TIME_FORMAT);
    }

    public static Date getTimePiece(Date d) {
        Calendar target = Calendar.getInstance();
        target.setTime(d);
        Calendar timePiece = Calendar.getInstance();
        timePiece.set(Calendar.MINUTE, 0);
        timePiece.set(Calendar.SECOND, 0);
        timePiece.set(Calendar.MILLISECOND, 0);
        timePiece.set(target.get(Calendar.YEAR), target.get(Calendar.MONTH), target.get(Calendar.DATE));
        int minute = target.get(Calendar.MINUTE);
        if (minute >= 45) {
            timePiece.set(Calendar.HOUR_OF_DAY, target.get(Calendar.HOUR_OF_DAY) + 1);
        } else {
            timePiece.set(Calendar.HOUR_OF_DAY, target.get(Calendar.HOUR_OF_DAY));
            if (minute >= 15) {
                timePiece.set(Calendar.MINUTE, 30);
            }
        }
        return timePiece.getTime();
    }

    public static Date minNotnull(Date date1, Date date2) {
        if (date2 == null) {
            return date1;
        } else if (date1 == null) {
            return date2;
        } else if (date2.before(date1)) {
            return date2;
        } else {
            return date1;
        }
    }

    public static Date maxNotnull(Date date1, Date date2) {
        if (date2 == null) {
            return date1;
        } else if (date1 == null) {
            return date2;
        } else if (date2.after(date1)) {
            return date2;
        } else {
            return date1;
        }
    }

    public static Date connect(Date d, Time t) {
        Calendar dc = Calendar.getInstance();
        dc.setTime(d);
        Calendar tc = Calendar.getInstance();
        tc.setTime(t);

        Calendar r = Calendar.getInstance();
        r.set(dc.get(Calendar.YEAR), dc.get(Calendar.MONTH), dc.get(Calendar.DATE), tc.get(Calendar.HOUR_OF_DAY), tc.get(Calendar.MINUTE),
                tc.get(Calendar.SECOND));
        return r.getTime();
    }

    public static boolean greaterEqThan24(String timeStr) {
        if (StringUtils.isNotEmpty(timeStr)) {
            String[] arr = timeStr.split("[-:]");
            try {
                if (Integer.parseInt(arr[0]) >= 24) {
                    return true;
                }
            } catch (Exception e) {
            }
        }
        return false;
    }

    public static boolean greaterThan24(String timeStr) {
        if (StringUtils.isNotEmpty(timeStr)) {
            String[] arr = timeStr.split("[-:]");
            try {
                if (Integer.parseInt(arr[0]) > 24) {
                    return true;
                } else {
                    if (Integer.parseInt(arr[0]) == 24) {
                        return Integer.parseInt(arr[1]) > 0;
                    }
                }
            } catch (Exception e) {
            }
        }
        return false;
    }

    private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {

        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat(DATA_TIME_FORMAT);
        }
    };

    public static Date getDateFromStr(String dateString) {
        try {
            return df.get().parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

}
